using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Threading;

namespace HubertTestProgram
{
   
    public abstract class BrainProcess  // : IBrainProcessGUI
    {
        #region Fields
        private int currentState;
        private string name;
        private double utility;
        private bool active;
        private Thread activeThread;
        private double brainProcessThreadSleepTime; // In s, of course ...
        private System.Diagnostics.Stopwatch stateWatch;
        #endregion

        private void IterateStep()
        {
            while (active)
            {
                Step();
                Thread.Sleep((int)(brainProcessThreadSleepTime*1000));
            }
        }

        private void ChangeCurrentState(int targetState)
        {      
            currentState = targetState;           
            stateWatch.Reset();
            stateWatch.Start();
        }

        #region Public methods
        public abstract void Step();

        public virtual void Initialize()
        {
            currentState = 0;
            stateWatch = new System.Diagnostics.Stopwatch();
        }

        public void SetActivityState()
        {
            if (utility > 0)
            {
                if (!this.Active)
                {
                    this.Active = true;
                }
            }
            else
            {
                this.Active = false;
            }
        }
        #endregion

        #region Properties
        public bool Active
        {
            get { return active; }
            set
            {
                active = value;
                if (active == true)
                {
                    ChangeCurrentState(0);
                    activeThread = new Thread(IterateStep);
                    activeThread.Start();
                }
                else
                {
                    if (activeThread is Thread && activeThread.IsAlive)
                        activeThread.Join();
                    currentState = 0;
                    stateWatch.Reset(); // Stops the stateWatch
                }
            }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }        
        public double Utility
        {
            get { return utility; }
            set { utility = value; }
        }
        public int CurrentState
        {
            get { return currentState; }
            set
            {
                ChangeCurrentState(value);
            }
        }
        public double TimeInState
        {
            get { return (double)stateWatch.ElapsedMilliseconds / 1000.0; }
        }
        public double BrainProcessThreadSleepTime
        {
            get { return brainProcessThreadSleepTime; }
            set { brainProcessThreadSleepTime = value; }
        }

        #endregion
        
    }
}
